package moe.feng.common.stepperview;

import moe.feng.common.stepperview.internal.ClipOvalFrameLayout;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.VectorElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.app.Context;

public class VerticalStepperItemView extends StackLayout {
    /**
     * Internal Views
     */
    private Component mPointBackground;
    private Component mLineView;
    private Text mPointNumber;
    private Text mTitleText;
    private Text mSummaryText;
    private StackLayout mCustomView;
    private StackLayout mPointFrame;
    private DirectionalLayout mRightContainer;
    private Image mDoneIconView;
    private Image mErrorIconView;
    private Component mMarginBottomView;
    private Image mAdapterImage;
    private AnimatorValue mTitleColorAnimator;
    private AnimatorValue mSummaryColorAnimator;
    private AnimatorValue mPointColorAnimator;
    private AnimatorProperty mPointAnimator;
    private AnimatorProperty mErrorIconAnimator;
    private AnimatorValue mErrorAnimator;

    /**
     * Step state
     */
    private String mTitle;
    private String mSummary = "";
    private String mSummaryFinished = "";
    private int mIndex = 1;
    private boolean isLastStep = false;
    private int mState = STATE_NORMAL;
    private String mErrorText = null; // If null means no error

    /**
     * View attributes
     */
    private int mAnimationDuration;
    private int mNormalColor;
    private int mActivatedColor;
    private int mLineColor;
    private int mErrorColor;

    private Element mDoneIcon;
    private boolean mAnimationEnabled = true;
    private boolean mAlwaysShowSummary = false;
    private VectorElement errorElement;
    private Image pointbackground;
    /**
     * The bind views
     */
    private VerticalStepperItemView mPrevItemView;
    private VerticalStepperItemView mNextItemView;
    public static final int STATE_NORMAL = 0;
    public static final int STATE_SELECTED = 1;
    public static final int STATE_DONE = 2;
    private final int DP;
    private int mAdapter = -1;

    public VerticalStepperItemView(Context context) {
        this(context, null);
    }

    public VerticalStepperItemView(Context context, int adapter) {
        this(context, null);
        mAdapter = adapter;
    }

    public VerticalStepperItemView(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public VerticalStepperItemView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);

        prepareViews(context);
        initColor();
        DP = 1;
        if (attrs != null) {
            mTitle = TypedAttrUtils.getString(attrs, "step_title", "");
            mSummary = TypedAttrUtils.getString(attrs, "step_summary", "");
            mSummaryFinished = TypedAttrUtils.getString(attrs, "step_summary_done", "");
            mIndex = TypedAttrUtils.getInteger(attrs, "step_index", 1);
            mState = TypedAttrUtils.getInteger(attrs, "step_state", STATE_NORMAL);
            isLastStep = TypedAttrUtils.getBoolean(attrs, "step_is_last", false);
            mNormalColor = TypedAttrUtils.getIntColor(attrs, "step_normal_color", mNormalColor);
            mActivatedColor = TypedAttrUtils.getIntColor(attrs, "step_activated_color", mActivatedColor);
            mAnimationDuration = TypedAttrUtils.getInteger(attrs, "step_animation_duration", mAnimationDuration);
            mAnimationEnabled = TypedAttrUtils.getBoolean(attrs, "step_enable_animation", true);
            mLineColor = TypedAttrUtils.getIntColor(attrs, "step_line_color", mLineColor);
            mErrorColor = TypedAttrUtils.getIntColor(attrs, "step_error_highlight_color", mErrorColor);
            mAlwaysShowSummary = TypedAttrUtils.getBoolean(attrs, "step_show_summary_always", mAlwaysShowSummary);
            if (null != TypedAttrUtils.getElement(attrs, "step_done_icon", null)) {
                mDoneIcon = TypedAttrUtils.getElement(attrs, "step_done_icon", null);
            } else {
                VectorElement mDoneIconElement = new VectorElement(context, ResourceTable.Graphic_ic_done_white_16dp);
                mDoneIconElement.setAntiAlias(true);
                mDoneIcon = mDoneIconElement;
            }
        }
        setTitle(mTitle);
        updateSummaryView();
        setIndex(mIndex);
        setIsLastStep(isLastStep);
        setDoneIcon(mDoneIcon);
        setAnimationEnabled(mAnimationEnabled);
        setLineColor(mLineColor,0);
        setErrorColor(mErrorColor);
        setState(mState);
    }

    private void initColor() {
        mNormalColor = Color.getIntColor("#9E9E9E");
        mActivatedColor = Color.getIntColor("#2196F3");
        mLineColor = Color.getIntColor("#9E9E9E");
        mErrorColor = Color.getIntColor("#F44336");
    }

    @Override
    public void addComponent(Component childComponent, int index, ComponentContainer.LayoutConfig layoutConfig) {
        if (childComponent.getId() == ResourceTable.Id_vertical_stepper_item_view_layout) {
            super.addComponent(childComponent, index, layoutConfig);
        } else {
            mCustomView.addComponent(childComponent, index, layoutConfig);
        }
    }

    public void addCustomViewComponet(Component component) {
        try {
            mCustomView.addComponent(component);
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    StackLayout getCustomView() {
        return mCustomView;
    }

    public void removeCustomView() {
        mCustomView.removeAllComponents();
    }

    private void prepareViews(Context context) {
        Component inflateView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_vertical_stepper_item_view_layout, null, false);
        mPointBackground = inflateView.findComponentById(ResourceTable.Id_stepper_point_background);
        mLineView = inflateView.findComponentById(ResourceTable.Id_stepper_line);
        mPointNumber = (Text) inflateView.findComponentById(ResourceTable.Id_stepper_number);
        mTitleText = (Text) inflateView.findComponentById(ResourceTable.Id_stepper_title);
        mSummaryText = (Text) inflateView.findComponentById(ResourceTable.Id_stepper_summary);
        mCustomView = (StackLayout) inflateView.findComponentById(ResourceTable.Id_stepper_custom_view);
        mPointFrame = (ClipOvalFrameLayout) inflateView.findComponentById(ResourceTable.Id_stepper_point_frame);
        mAdapterImage = (Image) inflateView.findComponentById(ResourceTable.Id_stepper_done_back_icon);
        mAdapterImage.setVisibility(HIDE);
        mRightContainer = (DirectionalLayout) inflateView.findComponentById(ResourceTable.Id_stepper_right_layout);
        mDoneIconView = (Image) inflateView.findComponentById(ResourceTable.Id_stepper_done_icon);
        mMarginBottomView = inflateView.findComponentById(ResourceTable.Id_stepper_margin_bottom);
        mErrorIconView = (Image) inflateView.findComponentById(ResourceTable.Id_stepper_error_icon);
        pointbackground = (Image) inflateView.findComponentById(ResourceTable.Id_stepper_back_error_icon);
        pointbackground.setVisibility(Component.HIDE);

        // Add view
        ComponentContainer.LayoutConfig lp = new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        addComponent(inflateView, lp);

        // Set title top margin
        mTitleText.getComponentTreeObserver().addGlobalFocusUpdatedListener(new ComponentTreeObserver.GlobalFocusUpdatedListener() {
            @Override
            public void onGlobalFocusUpdated(Component component, Component component1) {
                int singleLineHeight = mTitleText.getHeight();
                int topMargin = (mPointFrame.getHeight() - singleLineHeight) / 2;

                // Only update top margin when it is positive, preventing titles being truncated.
                if (topMargin > 0) {
                    ComponentContainer.LayoutConfig mlp = mTitleText.getLayoutConfig();
                    mlp.setMarginTop(topMargin);
                }
            }
        });
    }

    private void updateMarginBottom() {
        mMarginBottomView.getLayoutConfig().height = (!isLastStep ? (mState != STATE_SELECTED ? 28 : 36) : 12) * DP;
    }

    public void setState(int state) {
        mDoneIconView.setVisibility(VISIBLE);
        mPointNumber.setVisibility(VISIBLE);
        pointbackground.setVisibility(Component.HIDE);
        if (mPointColorAnimator != null) mPointColorAnimator.cancel();
        if (state != STATE_NORMAL && mState == STATE_NORMAL) {
            mErrorIconView.setVisibility(Component.HIDE);
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mNormalColor, mActivatedColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else if (state == STATE_NORMAL && mState != STATE_NORMAL) {
            mErrorIconView.setVisibility(Component.HIDE);
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mActivatedColor, mNormalColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else {
            mErrorIconView.setVisibility(Component.HIDE);
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setShape(ShapeElement.OVAL);
            shapeElement.setRgbColor(ViewUtils.getRgbColor(state == STATE_NORMAL ? mNormalColor : mActivatedColor));
            mPointBackground.setBackground(shapeElement);
        }
        if (state == STATE_DONE && mState != STATE_DONE) {
            mErrorIconView.setVisibility(Component.HIDE);
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(0f).setDuration(mAnimationDuration);
            animator1.start();
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(1f).setDuration(mAnimationDuration);
            animator.start();
        } else if (state != STATE_DONE && mState == STATE_DONE) {
            mErrorIconView.setVisibility(Component.HIDE);
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(0f).setDuration(mAnimationDuration);
            animator.start();
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(1f).setDuration(mAnimationDuration);
            animator1.start();
        } else {
            mErrorIconView.setVisibility(Component.HIDE);
            mDoneIconView.setAlpha(state == STATE_DONE ? 1f : 0f);
            mPointNumber.setAlpha(state == STATE_DONE ? 0f : 1f);
        }
        Color lastTitleTextColor = mTitleText.getTextColor();
        if (mTitleColorAnimator != null) mTitleColorAnimator.cancel();
        mTitleText.setFont(state == STATE_DONE ?
                Font.SANS_SERIF :
                state == STATE_NORMAL ?
                        Font.SANS_SERIF :
                        Font.SERIF);
        mTitleText.setTextColor(state != STATE_NORMAL ? Color.BLACK : new Color(Color.getIntColor("#7B7B7B")));

        // Update error state
        if (mErrorText != null) {
            mErrorIconView.setVisibility(Component.VISIBLE);
            mTitleColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mTitleText, "textColor", lastTitleTextColor, mErrorColor);
            mTitleColorAnimator.setDuration(mAnimationDuration);
            mTitleColorAnimator.start();
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mErrorColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mErrorIconView.getAlpha() < 1F) {
                mErrorIconView.setVisibility(Component.VISIBLE);
                mPointBackground.setVisibility(Component.HIDE);
                if (mAdapter == 0) {
                    pointbackground.setVisibility(VISIBLE);
                }
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.alpha(0f).setDuration(mAnimationDuration);
                mPointAnimator.start();
                mErrorIconView.setScaleX(0.6F);
                mErrorIconView.setScaleY(0.6F);
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.scaleX(1F).scaleY(1F)
                        .alpha(1F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        } else {
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mLineColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mPointFrame.getAlpha() < 1F) {
                mPointFrame.setScaleX(0.6F);
                mPointFrame.setScaleY(0.6F);
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.scaleX(1F).scaleY(1F).alpha(1F).setDuration(mAnimationDuration);
                mPointAnimator.start();
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.alpha(0F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        }
        mSummaryText.setVisibility(state != STATE_SELECTED && null != mSummary && !mSummary.equals("") ? Component.VISIBLE : Component.HIDE);
        mCustomView.setVisibility(state == STATE_SELECTED ? Component.VISIBLE : Component.HIDE);
        mState = state;
        updateMarginBottom();
        updateSummaryView();
    }

    public void setState(int state, int p, int a) {
        mErrorIconView.setVisibility(Component.HIDE);
        mDoneIconView.setVisibility(VISIBLE);
        mPointNumber.setVisibility(VISIBLE);
        pointbackground.setVisibility(Component.HIDE);
        mAdapterImage.setVisibility(HIDE);
        if (mPointColorAnimator != null) mPointColorAnimator.cancel();
        if (state != STATE_NORMAL && mState == STATE_NORMAL) {
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mNormalColor, mActivatedColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else if (state == STATE_NORMAL && mState != STATE_NORMAL) {
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mActivatedColor, mNormalColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setShape(ShapeElement.OVAL);
            shapeElement.setRgbColor(ViewUtils.getRgbColor(state == STATE_NORMAL ? mNormalColor : mActivatedColor));
            mPointBackground.setBackground(shapeElement);
        }
        if (state == STATE_DONE && mState != STATE_DONE) {
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(0f).setDuration(mAnimationDuration);
            animator1.start();
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(1f).setDuration(mAnimationDuration);
            animator.start();
            mPointNumber.setVisibility(HIDE);
            mDoneIconView.setVisibility(VISIBLE);
            mAdapterImage.setVisibility(VISIBLE);
        } else if (state != STATE_DONE && mState == STATE_DONE) {
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(0f).setDuration(mAnimationDuration);
            animator.start();
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(1f).setDuration(mAnimationDuration);
            animator1.start();
            mDoneIconView.setVisibility(HIDE);
            mPointNumber.setVisibility(VISIBLE);
        } else {
            mDoneIconView.setAlpha(state == STATE_DONE ? 1f : 0f);
            mPointNumber.setAlpha(state == STATE_DONE ? 0f : 1f);
            mDoneIconView.setVisibility(HIDE);
            mPointNumber.setVisibility(VISIBLE);
        }
        Color lastTitleTextColor = mTitleText.getTextColor();
        if (mTitleColorAnimator != null) mTitleColorAnimator.cancel();

        mTitleText.setFont(state == STATE_DONE ?
                Font.SANS_SERIF :
                state == STATE_NORMAL ?
                        Font.SANS_SERIF :
                        Font.SERIF);
        mTitleText.setTextColor(state != STATE_NORMAL ? Color.BLACK : new Color(Color.getIntColor("#7B7B7B")));
        if (mErrorText != null) {
            mTitleColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mTitleText, "textColor", lastTitleTextColor, mErrorColor);
            mTitleColorAnimator.setDuration(mAnimationDuration);
            mTitleColorAnimator.start();
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mErrorColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mErrorIconView.getAlpha() < 1F) {
                mPointBackground.setVisibility(Component.VISIBLE);
                mErrorAnimator = ViewUtils.createShowAnimator(pointbackground,mNormalColor,"background",mPointBackground);
                mErrorAnimator.setDuration(mAnimationDuration);
                mErrorAnimator.start();
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.alpha(0f).setDuration(mAnimationDuration);
                mPointAnimator.start();
                mErrorIconView.setScaleX(0.6F);
                mErrorIconView.setScaleY(0.6F);
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.scaleX(1F).scaleY(1F)
                        .alpha(1F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        } else {
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mLineColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mPointFrame.getAlpha() < 1F) {
                mPointFrame.setScaleX(0.6F);
                mPointFrame.setScaleY(0.6F);
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.scaleX(1F).scaleY(1F).alpha(1F).setDuration(mAnimationDuration);
                mPointAnimator.start();
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.alpha(0F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        }
        mSummaryText.setVisibility(state != STATE_SELECTED && null != mSummary && !mSummary.equals("") ? Component.VISIBLE : Component.HIDE);
        mCustomView.setVisibility(state == STATE_SELECTED ? Component.VISIBLE : Component.HIDE);
        mState = state;
        updateMarginBottom();
        updateSummaryView();
    }

    public void setState(int type, int state) {
        mErrorIconView.setVisibility(Component.HIDE);
        mDoneIconView.setVisibility(VISIBLE);
        mPointNumber.setVisibility(VISIBLE);
        if (mPointColorAnimator != null) mPointColorAnimator.cancel();
        if (state != STATE_NORMAL && mState == STATE_NORMAL) {
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mNormalColor, mActivatedColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else if (state == STATE_NORMAL && mState != STATE_NORMAL) {
            mPointColorAnimator = ViewUtils.createArgbAnimator(
                    mPointBackground, "backgroundColor", mActivatedColor, mNormalColor);
            mPointColorAnimator.setDuration(mAnimationDuration);
            mPointColorAnimator.start();
        } else {
            mPointBackground.setVisibility(VISIBLE);
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setShape(ShapeElement.OVAL);
            shapeElement.setRgbColor(ViewUtils.getRgbColor(state == STATE_NORMAL ? mNormalColor : mActivatedColor));
            mPointBackground.setBackground(shapeElement);
        }
        if (state == STATE_DONE && mState != STATE_DONE) {
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(0f).setDuration(mAnimationDuration);
            animator1.start();
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(1f).setDuration(mAnimationDuration);
            animator.start();
        } else if (state != STATE_DONE && mState == STATE_DONE) {
            AnimatorProperty animator = mDoneIconView.createAnimatorProperty();
            animator.alpha(0f).setDuration(mAnimationDuration);
            animator.start();
            AnimatorProperty animator1 = mPointNumber.createAnimatorProperty();
            animator1.alpha(1f).setDuration(mAnimationDuration);
            animator1.start();
        } else {
            if (type == 0) {
                mDoneIconView.setAlpha(state == STATE_DONE ? 1f : 0f);
                mPointNumber.setAlpha(state == STATE_DONE ? 0f : 1f);
                mPointNumber.setVisibility(HIDE);
                mDoneIconView.setVisibility(VISIBLE);
            }
        }
        Color lastTitleTextColor = mTitleText.getTextColor();
        if (mTitleColorAnimator != null) mTitleColorAnimator.cancel();

        mTitleText.setFont(state == STATE_DONE ?
                Font.SANS_SERIF :
                state == STATE_NORMAL ?
                        Font.SANS_SERIF :
                        Font.SERIF
        );
        mTitleText.setTextColor(state != STATE_NORMAL ? Color.BLACK : new Color(Color.getIntColor("#7B7B7B")));
        if (mErrorText != null) {
            mTitleColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mTitleText, "textColor", lastTitleTextColor, mErrorColor);
            mTitleColorAnimator.setDuration(mAnimationDuration);
            mTitleColorAnimator.start();
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mErrorColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mErrorIconView.getAlpha() < 1F) {
                mErrorIconView.setVisibility(Component.VISIBLE);
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.alpha(0f).setDuration(mAnimationDuration);
                mPointAnimator.start();
                mErrorIconView.setScaleX(0.6F);
                mErrorIconView.setScaleY(0.6F);
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.scaleX(1F).scaleY(1F)
                        .alpha(1F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        } else {
            if (mSummaryColorAnimator != null) mSummaryColorAnimator.cancel();
            mSummaryColorAnimator = ViewUtils.createArgbAnimatorColor(
                    mSummaryText, "textColor", mSummaryText.getTextColor(), mLineColor);
            mSummaryColorAnimator.setDuration(mAnimationDuration);
            mSummaryColorAnimator.start();
            if (mPointFrame.getAlpha() < 1F) {
                mPointFrame.setScaleX(0.6F);
                mPointFrame.setScaleY(0.6F);
                if (mPointAnimator != null) mPointAnimator.cancel();
                mPointAnimator = mPointFrame.createAnimatorProperty();
                mPointAnimator.scaleX(1F).scaleY(1F).alpha(1F).setDuration(mAnimationDuration);
                mPointAnimator.start();
                if (mErrorIconAnimator != null) mErrorIconAnimator.cancel();
                mErrorIconAnimator = mErrorIconView.createAnimatorProperty();
                mErrorIconAnimator.alpha(0F).setDuration(mAnimationDuration).setCurveType(Animator.CurveType.ANTICIPATE);
                mErrorIconAnimator.start();
            }
        }
        mSummaryText.setVisibility(state != STATE_SELECTED && null != mSummary && !mSummary.equals("") ? Component.VISIBLE : Component.HIDE);
        mCustomView.setVisibility(state == STATE_SELECTED ? Component.VISIBLE : Component.HIDE);
        mState = state;
        updateMarginBottom();
        updateSummaryView();
    }


//    public int getState() {
//        return mState;
//    }

    /**
     * Set title for this step
     *
     * @param title The title should be set
     */
    public void setTitle(String title) {
        mTitle = title;
        mTitleText.setText(title);
    }

    /**
     * Get the title of this step
     *
     * @return The title of this step
     */
    public String getTitle() {
        return mTitle;
    }

    /**
     * Set should show summary always.
     *
     * @param alwaysShowSummary new value
     */
    public void setAlwaysShowSummary(boolean alwaysShowSummary) {
        mAlwaysShowSummary = alwaysShowSummary;
        updateSummaryView();
    }

    /**
     * Should show summary always
     *
     * @return If should show summary always
     */
    public boolean isAlwaysShowSummary() {
        return mAlwaysShowSummary;
    }

    /**
     * Set error text for this step. If you want to remove error text, the param should be null.
     *
     * @param errorText The error text should be set or zero for removing error text
     */
    public void setErrorText(String errorText) {
        mErrorText = errorText;
        mSummaryText.setText(mErrorText != null ? mErrorText : null != mSummary ? mSummary : "");
        setState(mState);
    }

    public void setErrorText(int type, String errorText) {
        mErrorText = errorText;
        mSummaryText.setText(mErrorText != null ? mErrorText : null != mSummary ? mSummary : "");
        setState(type, mState);
    }

    /**
     * Get the title of this step
     *
     * @return The title of this step
     */
    public String getErrorText() {
        return mErrorText;
    }

    /**
     * Set summary for this step.
     * If you set a null value, it will hide the summary view.
     *
     * @param summary The summary should be set or null
     */
    public void setSummary(String summary) {
        mSummary = summary;
        updateSummaryView();
    }

    /**
     * Get the summary of this step
     *
     * @return The summary of this step
     */
    public String getSummary() {
        return mSummary;
    }

    /**
     * Set finished summary for this step.
     * If you set a null value, it will hide the summary view or show default summary.
     *
     * @param summary The summary should be set or null
     */
    public void setSummaryFinished(String summary) {
        mSummaryFinished = summary;
        updateSummaryView();
    }

    /**
     * Get the summary of this step
     *
     * @return The summary of this step
     */
    public String getSummaryFinished() {
        return mSummaryFinished;
    }

    /**
     * Update summary view
     */
    private void updateSummaryView() {
        mSummaryText.setText(
                mErrorText != null ? mErrorText
                        : (mSummaryFinished != null && mState == STATE_DONE) ? mSummaryFinished : mSummary
        );
        mSummaryText.setVisibility(
                (mState != STATE_SELECTED || mAlwaysShowSummary) && !mSummaryText.getText().toString().equals("") ?
                        Component.VISIBLE : Component.HIDE
        );
    }

    /**
     * Set index for this step
     *
     * @param index Index
     */
    public void setIndex(int index) {
        mIndex = index;
        mPointNumber.setText(String.valueOf(index));
    }

    /**
     * Get the index of this step
     *
     * @return The index of this step
     */
    public int getIndex() {
        return mIndex;
    }

    /**
     * Set if it is last step
     *
     * @param isLastStep If it is last step
     */
    public void setIsLastStep(boolean isLastStep) {
        this.isLastStep = isLastStep;
        mLineView.setVisibility(isLastStep ? Component.INVISIBLE : Component.VISIBLE);
        updateMarginBottom();
    }

    /**
     * Return if it is last step
     *
     * @return If it is last step
     */
    public boolean isLastStep() {
        return isLastStep;
    }

    /**
     * Set if animation should be enabled
     *
     * @param shouldAnimate If animation should be enabled
     */
    public void setAnimationEnabled(boolean shouldAnimate) {
        mAnimationEnabled = shouldAnimate;
        if (shouldAnimate) {
        } else {
            mRightContainer.setComponentTransition(null);
        }
    }

    /**
     * Get if animation is enabled
     *
     * @return If animation is enabled
     */
    public boolean isAnimationEnabled() {
        return mAnimationEnabled;
    }

    /**
     * Set done icon drawable
     *
     * @param drawable Done icon drawable
     */
    public void setDoneIcon(Element drawable) {
        mDoneIconView.setImageElement(null);
        mDoneIcon = drawable;
        mDoneIconView.setImageElement(drawable);
        mAdapterImage.setBackground(drawable);
    }

    /**
     * Set done icon drawable resource
     *
     * @param drawableRes Done icon drawable resource
     */
    public void setDoneIconResource(int drawableRes) {
        VectorElement mVectorElement = new VectorElement(mContext, drawableRes);
        mVectorElement.setAntiAlias(true);
        setDoneIcon(mVectorElement);
    }

    /**
     * Get done icon drawable
     *
     * @return Done icon drawable
     */
    public Element getDoneIcon() {
        return mDoneIcon;
    }

    /**
     * Set animation duration
     *
     * @param duration Animation Duration
     */
    public void setAnimationDuration(int duration) {
        mAnimationDuration = duration;
    }

    /**
     * Get animation duration
     *
     * @return Animation Duration
     */
    public int getAnimationDuration() {
        return mAnimationDuration;
    }

    /**
     * Bind two stepper items for automatically setting state with nextStep() or prevStep()
     *
     * @param prevItem The previous item
     * @param nextItem The next item
     */
    public void bindSteppers(VerticalStepperItemView prevItem, VerticalStepperItemView nextItem) {
        if (prevItem != null) {
            mPrevItemView = prevItem;
            if (mPrevItemView.mNextItemView != this) {
                mPrevItemView.bindSteppers(null, this);
            }
        }
        if (nextItem != null) {
            mNextItemView = nextItem;
            if (mNextItemView.mPrevItemView != this) {
                mNextItemView.bindSteppers(this, null);
            }
        }
    }

    /**
     * Bind stepper items for automatically setting state with nextStep() or prevStep()
     *
     * @param items Stepper items
     */
    public static void bindSteppers(VerticalStepperItemView... items) {
        for (int i = 0; i < items.length - 1; i++) {
            if (i != 0) {
                items[i].bindSteppers(items[i - 1], null);
            }
            items[i].bindSteppers(null, items[i + 1]);
        }
    }

    /**
     * Return if stepper can go previous
     *
     * @return If stepper can go previous
     */
    public boolean canPrevStep() {
        return mPrevItemView != null;
    }

    /**
     * Go previous step
     *
     * @return If success
     */
    public boolean prevStep() {
        if (canPrevStep()) {
            setState(STATE_NORMAL);
            if (mPrevItemView != null) {
                mPrevItemView.setState(STATE_SELECTED);
            }
            return true;
        }
        return false;
    }

    /**
     * Return if stepper can go next
     *
     * @return If stepper can go next
     */
    public boolean canNextStep() {
        return mNextItemView != null;
    }

    /**
     * Go next step
     *
     * @return If success
     */
    public boolean nextStep() {
        if (canNextStep()) {
            setState(STATE_DONE);
            if (mNextItemView != null) {
                mNextItemView.setState(STATE_SELECTED);
            }
            return true;
        }
        return false;
    }

    /**
     * Set normal point color
     *
     * @param color Normal Point Color
     */
    public void setNormalColor(int color) {
        mNormalColor = color;
        if (mState == STATE_NORMAL) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(ViewUtils.getRgbColor(color));
            mPointBackground.setBackground(shapeElement);
        }
    }

    /**
     * Get normal point color
     *
     * @return Normal Point Color
     */
    public int getNormalColor() {
        return mNormalColor;
    }

    /**
     * Set activated point color
     *
     * @param color Activated Point Color
     */
    public void setActivatedColor(int color) {
        mActivatedColor = color;
        if (mState != STATE_NORMAL) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(ViewUtils.getRgbColor(color));
            shapeElement.setShape(ShapeElement.OVAL);
            mPointBackground.setBackground(shapeElement);
        }
    }

    /**
     * Get line color
     *
     * @return Line Color
     */
    public int getLineColor() {
        return mLineColor;
    }
    public void setLineColor(int color,int type) {
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(ViewUtils.getRgbColor(color));
        mLineColor = color;
        mLineView.setBackground(shapeElement);
        if(type==1) {
            mLineView.setMarginBottom(20);
        }
    }

    /**
     * Get error highlight color
     *
     * @return Error Highlight Color
     */
    public int getErrorColor() {
        return mErrorColor;
    }

    /**
     * Set error highlight color
     *
     * @param color Error Highlight Color
     */
    public void setErrorColor(int color) {
        errorElement = new VectorElement(mContext, ResourceTable.Graphic_ic_warning_black_24dp);
        errorElement.setAntiAlias(true);
        Element error;
        if (mErrorColor != 0) {
            error = ElementColorUtil.getTintElement(errorElement, mErrorColor);
        } else {
            error = ElementColorUtil.getTintElement(errorElement, "#F44336");
        }
        mErrorIconView.setImageElement(error);
        mErrorIconView.setAlpha(0f);
        mErrorIconView.setVisibility(Component.HIDE);
        if (mErrorText != null && color != mErrorColor) {
            if (mTitleColorAnimator != null && mTitleColorAnimator.isRunning()) mTitleColorAnimator.cancel();
            if (mSummaryColorAnimator != null && mSummaryColorAnimator.isRunning()) mSummaryColorAnimator.cancel();
            mTitleText.setTextColor(new Color(color));
            mSummaryText.setTextColor(new Color(color));
        }
        mErrorColor = color;
    }

    /**
     * Get activated point color
     *
     * @return Activated Point Color
     */
    public int getActivatedColor() {
        return mActivatedColor;
    }

    private static boolean isPreLollipop() {
        return true;
    }

}